/**
 * Entity - 游戏实体基类
 * 所有游戏对象（玩家、障碍物、道具等）的基础类
 */

import type { Vector2D } from './GameEngine'
import type { Poolable } from './ObjectPool'

export interface Sprite {
  image?: HTMLImageElement
  x: number
  y: number
  width: number
  height: number
  frameX?: number
  frameY?: number
  frameWidth?: number
  frameHeight?: number
}

export enum EntityType {
  PLAYER = 'player',
  OBSTACLE = 'obstacle',
  POWERUP = 'powerup',
  COLLECTIBLE = 'collectible',
  BACKGROUND = 'background',
  PROJECTILE = 'projectile',
  BOSS = 'boss'
}

export interface EntityOptions {
  id?: string
  x: number
  y: number
  width: number
  height: number
  type: EntityType
  sprite?: Sprite
  velocity?: Vector2D
}

export abstract class Entity implements Poolable {
  public readonly id: string
  public x: number
  public y: number
  public width: number
  public height: number
  public velocity: Vector2D
  public sprite: Sprite | null
  public readonly type: EntityType
  public active: boolean = true
  public visible: boolean = true

  constructor(options: EntityOptions) {
    this.id = options.id || this.generateId()
    this.x = options.x
    this.y = options.y
    this.width = options.width
    this.height = options.height
    this.type = options.type
    this.velocity = options.velocity || { x: 0, y: 0 }
    this.sprite = options.sprite || null
  }

  /**
   * 生成唯一ID
   */
  private generateId(): string {
    return `${this.type}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 更新实体逻辑
   * @param deltaTime 距离上一帧的时间差（毫秒）
   */
  abstract update(deltaTime: number): void

  /**
   * 渲染实体
   * @param ctx Canvas渲染上下文
   */
  render(ctx: CanvasRenderingContext2D): void {
    if (!this.visible) return

    if (this.sprite && this.sprite.image) {
      this.renderSprite(ctx)
    } else {
      this.renderDefault(ctx)
    }
  }

  /**
   * 渲染精灵图像
   */
  private renderSprite(ctx: CanvasRenderingContext2D): void {
    if (!this.sprite || !this.sprite.image) return

    const sprite = this.sprite
    
    if (sprite.image && sprite.frameWidth && sprite.frameHeight) {
      // 渲染精灵表中的特定帧
      ctx.drawImage(
        sprite.image,
        sprite.frameX || 0,
        sprite.frameY || 0,
        sprite.frameWidth,
        sprite.frameHeight,
        this.x,
        this.y,
        this.width,
        this.height
      )
    } else if (sprite.image) {
      // 渲染整个图像
      ctx.drawImage(
        sprite.image,
        this.x,
        this.y,
        this.width,
        this.height
      )
    }
  }

  /**
   * 默认渲染（矩形）
   */
  protected renderDefault(ctx: CanvasRenderingContext2D): void {
    ctx.fillStyle = this.getDefaultColor()
    ctx.fillRect(this.x, this.y, this.width, this.height)
    
    // 绘制边框
    ctx.strokeStyle = '#000000'
    ctx.lineWidth = 1
    ctx.strokeRect(this.x, this.y, this.width, this.height)
  }

  /**
   * 获取默认颜色（子类可以重写）
   */
  protected getDefaultColor(): string {
    switch (this.type) {
      case EntityType.PLAYER:
        return '#4CAF50'
      case EntityType.OBSTACLE:
        return '#F44336'
      case EntityType.POWERUP:
        return '#FF9800'
      case EntityType.COLLECTIBLE:
        return '#FFEB3B'
      case EntityType.BACKGROUND:
        return '#E0E0E0'
      case EntityType.PROJECTILE:
        return '#2196F3'
      default:
        return '#9E9E9E'
    }
  }

  /**
   * 销毁实体
   */
  destroy(): void {
    this.active = false
    this.visible = false
  }

  /**
   * 检查是否需要被移除
   */
  shouldBeRemoved(): boolean {
    return !this.active
  }

  /**
   * 获取边界框
   */
  getBounds(): { x: number; y: number; width: number; height: number } {
    return {
      x: this.x,
      y: this.y,
      width: this.width,
      height: this.height
    }
  }

  /**
   * 获取中心点
   */
  getCenter(): Vector2D {
    return {
      x: this.x + this.width / 2,
      y: this.y + this.height / 2
    }
  }

  /**
   * 设置位置
   */
  setPosition(x: number, y: number): void {
    this.x = x
    this.y = y
  }

  /**
   * 设置速度
   */
  setVelocity(x: number, y: number): void {
    this.velocity.x = x
    this.velocity.y = y
  }

  /**
   * 应用基础物理更新（位置 += 速度 * 时间）
   */
  protected applyPhysics(deltaTime: number): void {
    const deltaSeconds = deltaTime / 1000
    this.x += this.velocity.x * deltaSeconds
    this.y += this.velocity.y * deltaSeconds
  }

  /**
   * 检查是否在屏幕范围内
   */
  isInBounds(screenWidth: number, screenHeight: number, margin: number = 0): boolean {
    return (
      this.x + this.width >= -margin &&
      this.x <= screenWidth + margin &&
      this.y + this.height >= -margin &&
      this.y <= screenHeight + margin
    )
  }

  /**
   * 重置实体状态，准备重用（对象池接口实现）
   */
  reset(): void {
    this.active = true
    this.visible = true
    this.x = 0
    this.y = 0
    this.velocity.x = 0
    this.velocity.y = 0
    this.sprite = null
  }

  /**
   * 检查对象是否可以回收到池中（对象池接口实现）
   * @returns 如果对象可以被池化返回true
   */
  canBePooled(): boolean {
    return !this.active && !this.visible
  }
}